import {
    defineStore
} from 'pinia'
import {
    ref
} from 'vue'
import storage from '@/utils/storage'
import {
    getToken,
    removeToken,
    setToken
} from '@/utils/auth'
import {
    getRole
} from "@/api/user"
import {
    getDriverTask,
    pushPosition
} from "@/api/driver"
import {
    toast
} from '@/utils/common'
import type { uniRequestRes } from "@/types"


export const useUserStore = defineStore('user', () => {

    /* 数据缓存 */
    const token = ref(getToken())
    const username = ref(storage.get("username"))
    // 登录后角色
    const role = ref(storage.get("role"))
    // 登录前角色选择
    const loginRole = ref('')
    // 获取司机用户进行中运单的定时器
    const getWaybillTimer = ref<number | null>(null)
    // 运单
    const shipId = ref('')
    // 获取位置定时器
    const timer = ref<number | null>(null)




    /* 方法 */
    // 普通方法
    // 设置每一分钟获取一次位置推送给服务器
    const setGetLocationTimer = async () => {
        if (!token.value) return
        if (!shipId.value) return
        if (role.value === 'driver') {
            await handleLocation()
            timer.value = Number(setInterval(async () => {
                await handleLocation()
            }, 60 * 1000))
        }
    }
    // 获取定位后方法封装
    const handleLocation = async () => {
        try {
            if (!token.value) return
            if (!shipId.value) return
            let { authSetting } = await uni.getSetting() as any
            if (authSetting && authSetting['scope.userLocation']) {
                // 已授权定位权限
                let res: any = await getLocation()
                if (!(res.latitude && res.longitude)) return

                // 推送位置信息到服务器
                await pushPosition({
                    shipId: shipId.value,
                    lon: res.longitude.toString(),
                    lat: res.latitude.toString()
                })
                console.log("======位置======")
                console.log("======纬度======", res.latitude.toString())
                console.log("======经度======", res.longitude.toString())
            } else {
                // 未授权，请求授权
                let authorizeResult = await uni.authorize({
                    scope: 'scope.userLocation'
                }) as unknown as { errMsg: string }
                let { errMsg } = authorizeResult
                if (errMsg === 'authorize:ok') {
                    // 已授权定位权限
                    let res: any = await getLocation()
                    if (!(res.latitude && res.longitude)) return

                    // 推送位置信息到服务器
                    await pushPosition({
                        shipId: shipId.value,
                        lon: res.longitude.toString(),
                        lat: res.latitude.toString()
                    })
                    console.log("======位置======");
                    console.log("======纬度======", res.latitude.toString());
                    console.log("======经度======", res.longitude.toString());
                }
            }
        } catch (err: any) {
            // 拒绝授权
            if (err.errMsg.includes('auth deny')) {
                uni.showModal({
                    title: '提示',
                    content: '需要位置权限才能使用该功能，请前往设置开启',
                    success: (res) => {
                        if (res.confirm) {
                            // 跳转到小程序设置页
                            uni.openSetting()
                        }
                    }
                })
            } else {
                toast('获取定位失败' + err.errMsg)
            }
        }
    }
    // 获取定位
    const getLocation = async () => {
        return new Promise((resolve, reject) => {
            uni.getLocation({
                type: 'gcj02',
                isHighAccuracy: true,
                timeout: 10000,
                highAccuracyExpireTime: 5000,
                success: (res: UniApp.GetLocationSuccess) => resolve(res),
                fail: (err: any) => reject(err)
            })
        })
    }
    // 登录后获取用户角色
    const getUserRole = async () => {
        let res = await getRole() as uniRequestRes
        if (res.success) {
            if (res.data.includes('captain')) {
                role.value = 'captain'
                storage.set("role", 'captain')
            } else {
                role.value = 'driver'
                storage.set("role", 'driver')
            }
        }
    }
    // 获取司机用户进行中运单
    const getProgressWaybill = async () => {
        if (!token.value) return
        let res = await getDriverTask({
            currPage: 1,
            limit: 10,
            status: 'PROGRESS'
        }) as uniRequestRes
        if (res.success) {
            if (res.data.list.length > 0) {
                shipId.value = res.data.list[0].id
                if (!timer.value) {
                    // 获取运单信息之后设置位置推送定时器
                    await setGetLocationTimer()
                }
            } else {
                shipId.value = ''
            }
        }
    }

    //暴露的方法
    // 设置定时器，每五分钟获取司机用户进行中运单
    const setGetWaybillTimer = async () => {
        if (!token.value) return
        if (role.value === 'driver') {
            //首次获取
            await getProgressWaybill()
            getWaybillTimer.value = Number(setInterval(async () => {
                await getProgressWaybill()
            }, 5 * 60 * 1000))
        }
    }
    // 清除定时器
    const clearGetWaybillTimer = () => {
        if (getWaybillTimer.value) {
            clearInterval(getWaybillTimer.value)
            getWaybillTimer.value = null
        }
        if (timer.value) {
            clearInterval(timer.value)
            timer.value = null
        }
    }
    const SET_TOKEN = (val: string) => {
        token.value = val
    }
    const STE_USERNAME = (v: string) => {
        username.value = v
    }

    const LOGIN_SUCC = async (t: string, u: string) => {
        SET_TOKEN(t)
        STE_USERNAME(u)
        setToken(t)
        storage.set("username", u)
        await getUserRole()
        await setGetWaybillTimer()
    }

    const LOGOUT = () => {
        SET_TOKEN('')
        STE_USERNAME('')
        removeToken()
        storage.remove("username")
        storage.remove("role")
    }

    const SETLOGINROLE = (v: string) => {
        loginRole.value = v
    }


    return {
        token,
        username,
        loginRole,
        role,
        SET_TOKEN,
        STE_USERNAME,
        LOGIN_SUCC,
        LOGOUT,
        SETLOGINROLE,
        setGetWaybillTimer,
        clearGetWaybillTimer
    }
})